
package cz.incad.psh.pshassign.server;

import com.google.gwt.regexp.shared.MatchResult;
import com.google.gwt.regexp.shared.RegExp;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import org.json.JSONArray;
import org.json.JSONObject;

/**
 *
 * @author Alberto Hernandez
 */
public class Candidate {
    double score;
    double rank;
    String root;
    boolean isExact;
    boolean isMultiple;
    String uri;;
    String label;
    String label_en;
    String path;
    JSONObject json;
    JSONObject hlObject;
    JSONObject rank_explain;
    
    String docId;
    
    ArrayList<String> words =  new ArrayList<String>();
    //HashMap<String, Integer> proximity = new HashMap<String, Integer>();
//    public Candidate(String label, String uri, double score, String root, 
//            JSONObject uriObject, ArrayList<String> words, double rank, String path){
//        Set fields = uriObject.keySet();
//        for (Iterator iter2 = fields.iterator(); iter2.hasNext();) {
//            String field = (String) iter2.next();
//            JSONArray fArray = uriObject.getJSONArray(field);
//            for (int k = 0; k < fArray.length(); k++) {
//                String hit = fArray.getString(k);
//                setIsExact(hit);
//                setIsMultiple(hit);
//            }
//        }
//        this.uri = uri;
//        this.label = label;
//        this.score = score;
//        this.rank = rank;
//        this.root = root;
//        this.path = path;
//        this.words.addAll(words);
//        this.hlObject = uriObject;
//    }
    
    public Candidate(JSONObject json,JSONObject uriObject, ArrayList<String> words, String docId){
        this.json = json;
        this.root = json.getJSONArray("path").getString(0).substring(1).split("/")[0];
        this.uri = json.getString("uri");
        this.docId = docId;
        this.label = json.getJSONArray("csPrefLabel").getString(0);
        this.label_en = json.getJSONArray("enPrefLabel").getString(0);
        this.path = json.getJSONArray("path").getString(0);
        this.score = json.getDouble("score");
        this.rank = json.getDouble("rank");
        this.rank_explain = json.getJSONObject("rank_explain");
        this.hlObject = uriObject;
        this.words.addAll(words);
        Set fields = uriObject.keySet();
        for (Iterator iter2 = fields.iterator(); iter2.hasNext();) {
            String field = (String) iter2.next();
            JSONArray fArray = uriObject.getJSONArray(field);
            for (int k = 0; k < fArray.length(); k++) {
                String hit = fArray.getString(k);
                setIsExact(hit);
                setIsMultiple(hit);
            }
        }
        
    }
    
    public void addProximity(double prox, double boost){
        rank = rank + prox * boost;
        json.put("proximity", prox);
    }
    
    public int getLevel(){
        return json.getInt("level");
    }
    
    public int getProximity(){
        return json.getInt("proximity");
    }
    
    public JSONObject getHlObject(){
        return hlObject;
    }
    public JSONObject getRank_explain(){
        return rank_explain;
    }
    public String getPath(){
        return path;
    }
    public String getUri(){
        return uri;
    }
    
    public String getLabel(){
        return label;
    }
    
    public String getLabel_en(){
        return label_en;
    }
    
    public double getScore(){
        return score;
    }
    
    public double getRank(){
        return rank;
    }
    
    public String getRoot(){
        return root;
    }
    
    public boolean getIsExact(){
        return isExact;
    }
    
    public boolean getIsMultiple(){
        return isMultiple;
    }
    
    public ArrayList<String> getWords(){
        return words;
    }
    
    private int getNumHits(String s) {
        int res = 0;
        String patternStr = "<b>(.*?)<\\/b>";
        RegExp regExp = RegExp.compile(patternStr, "ig");
        
        for (MatchResult matcher = regExp.exec(s); matcher != null; matcher = regExp.exec(s)) {
            res++;
         }
        return res;
    }

    private int count(final String string, final String substring) {
        int count = 0;
        int idx = 0;

        while ((idx = string.indexOf(substring, idx)) != -1) {
            idx++;
            count++;
        }

        return count;
    }

    private void setIsExact(String hit) {
//        int numHits = getNumHits(hit);
        int numWords = count(hit, " ") + count(hit, "-") + 1;
//        isExact = (numHits == numWords) || isExact;
        

        isExact = (numWords==1) ||
                cz.incad.psh.pshassign.server.search.ProximitySearch.isNear(hit.replaceAll("<b>", "").replaceAll("</b>", ""), docId) ||
                isExact;
        
    }

    private void setIsMultiple(String hit) {
        isMultiple = (getNumHits(hit) > 1) || isMultiple;
    }
}
